package bg.btanev.eightyfour.hibernate.dialect;

import java.sql.SQLException;

import org.hibernate.dialect.PostgreSQLDialect;
import org.hibernate.exception.ViolatedConstraintNameExtracter;

/**
 * <p>
 * This class subclasses the original {@link PostgreSQLDialect} to patch some bugs. It <a
 * href="http://en.wikipedia.org/wiki/Decorator_pattern">decorates</a> the {@link ViolatedConstraintNameExtracter} to
 * search for the name of the constraint in nested {@link SQLException}.
 * </p>
 *
 * @author B. Tanev
 */
public class CustomHibernatePostgreSQLDialect extends PostgreSQLDialect {

	/**
	 * The decorator class.
	 *
	 */
	private static class ExtracterDecorator implements ViolatedConstraintNameExtracter {
		ViolatedConstraintNameExtracter originalExtractor;

		private ExtracterDecorator(ViolatedConstraintNameExtracter originalExtractor) {
			this.originalExtractor = originalExtractor;
		}

		public String extractConstraintName(SQLException sqlException) {
			String constraintName = originalExtractor.extractConstraintName(sqlException);
			SQLException nested = sqlException.getNextException();
			while (constraintName == null && nested != null) {
				constraintName = originalExtractor.extractConstraintName(nested);
				nested = nested.getNextException();
			}
			return constraintName;
		}
	}

	private ExtracterDecorator decorator = new ExtracterDecorator(super.getViolatedConstraintNameExtracter());

	/**
	 * {@inheritDoc}
	 */
	@Override
	public ViolatedConstraintNameExtracter getViolatedConstraintNameExtracter() {
		return decorator;
	}
}
